/**
 ****************************************************************************
 * Copyright (C) Marcelo F. Ochoa. All rights reserved.                      *
 * ------------------------------------------------------------------------- *
 * This software is published under the terms of the Apache Software License *
 * version 1.1, a copy of which has been included  with this distribution in *
 * the LICENSE file.                                                         *
 */

package com.prism.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Properties;
import java.util.StringTokenizer;

import org.jconfig.Configuration;
import org.jconfig.ConfigurationManager;
import org.jconfig.ConfigurationManagerException;
import org.jconfig.handler.XMLFileHandler;

public class MigrateProperties  {

  private Properties properties;
  private Configuration configuration;
  private ConfigurationManager cm;
  private XMLFileHandler handler;
  
  public MigrateProperties(File propFileName,
                           File confFileName) 
    throws Exception {
    InputStream in = null;
    cm = ConfigurationManager.getInstance();
    handler = new XMLFileHandler();
    handler.setFile(confFileName);
    cm.load(handler,"prism.xconf");
    configuration = cm.getConfiguration("prism.xconf");
    in = new FileInputStream(propFileName);
    properties = new Properties();
    properties.load(in);
    in.close();  
  }

  private void save() throws ConfigurationManagerException {
    cm.save(handler,configuration);
  }
  
  private void global() {
    String LANG = properties.getProperty("global.lang");
    String COUNTRY = properties.getProperty("global.country");
    String WEBMASTER = (WEBMASTER = properties.getProperty("global.webmaster")) != null ? WEBMASTER : "webmaster@yourdomain.com";
    String CONTENTTYPE = (CONTENTTYPE = properties.getProperty("global.contenttype")) != null ? CONTENTTYPE : "text/html";
    String UnauthorizedText = (UnauthorizedText = properties.getProperty("global.UnauthorizedText")) != null ? UnauthorizedText :
            "You must be enter DB username and password to access at the system";
    int BEHAVIOR,maxUploadSize;
    try {
      BEHAVIOR = (new Integer(properties.getProperty("global.behavior"))).intValue();
    } catch (Exception e) { BEHAVIOR = 0; };
    try {
      maxUploadSize = (new Integer(properties.getProperty("global.maxUploadSize"))).intValue() * 1024;
    } catch (Exception e) { maxUploadSize = 8192 * 1024; };
    boolean cachep = "true".equalsIgnoreCase(properties.getProperty("global.cacheprocedure"));
    String compatList = properties.getProperty("global.compatlist");
    String flexibleRequest = (flexibleRequest=properties.getProperty("global.flexibleRequest"))
                              !=null ? flexibleRequest : "old" ;
    boolean flexibleCompact = flexibleRequest.equalsIgnoreCase("compact");
    String connAlias = (connAlias=properties.getProperty("global.alias"))
                         !=null ? connAlias : "" ;
    if (LANG!=null)
      configuration.setProperty("lang",LANG);
    if (COUNTRY!=null)
      configuration.setProperty("country",COUNTRY);
    configuration.setProperty("webmaster",WEBMASTER);
    configuration.setProperty("contenttype",CONTENTTYPE);
    configuration.setProperty("UnauthorizedText",UnauthorizedText);
    configuration.setProperty("behavior",""+BEHAVIOR);
    configuration.setProperty("maxUploadSize",""+maxUploadSize);
    configuration.setProperty("compatlist",compatList);
    configuration.setProperty("flexibleRequest",flexibleRequest);
    configuration.setProperty("alias",connAlias);
  }

  private void Factories() {
    configuration.setCategory("factory");
    String compatList = properties.getProperty("global.compatlist");
    StringTokenizer st = new StringTokenizer(compatList, " ");
    while (st.hasMoreElements()) {
      String strcompat = (String)st.nextElement();
      String factory = properties.getProperty("factory." + strcompat);
      configuration.setProperty(strcompat,factory,"factory");
    }
  }

  private void Drivers() {
    configuration.setCategory("jdbcDriver");
    String compatList = properties.getProperty("global.compatlist");
    StringTokenizer st = new StringTokenizer(compatList, " ");
    while (st.hasMoreElements()) {
      String strcompat = (String)st.nextElement();
      String JdbcDriver = properties.getProperty("jdbcDriver." + strcompat);
      configuration.setProperty(strcompat,JdbcDriver,"jdbcDriver");
    }
  }
  
  private void Manager() {
    configuration.setCategory("Manager");
    String managerClass = properties.getProperty("Manager.class");
    String txList = properties.getProperty("Manager.TxNames");
    if (managerClass == null) {
      System.out.println("Warning: Manager.class is not set");
      System.out.println("         Using com.prism.utils.JdbcDBPrismConnectionCacheImpl");
      managerClass = "com.prism.utils.JdbcDBPrismConnectionCacheImpl";
    }
    boolean txEnableProcessing = "true".equalsIgnoreCase(properties.getProperty("Manager.TxEnable"));
    int connectionTimeOut;
    try {
      connectionTimeOut = (new Integer(properties.getProperty("Manager.timeout"))).intValue();
    } catch (Exception e) { connectionTimeOut = 600; };

    // JdbcConnectionCacheImpl specific parameters
    if ("com.prism.utils.JdbcDBPrismConnectionCacheImpl".equals(managerClass)) {
      int minConnections;
      try {
        minConnections = (new Integer(properties.getProperty("Manager.minconnections"))).intValue();
      } catch (Exception e) { minConnections = 0; };
      int maxConnections;
      try {
        maxConnections = (new Integer(properties.getProperty("Manager.maxconnections"))).intValue();
      } catch (Exception e) { maxConnections = 20; };
      configuration.setProperty("minconnections",""+minConnections,"Manager");
      configuration.setProperty("maxconnections",""+maxConnections,"Manager");
    }
    configuration.setProperty("class",managerClass,"Manager");
    configuration.setProperty("TxEnable",""+txEnableProcessing,"Manager");
    configuration.setProperty("timeout",""+connectionTimeOut,"Manager");
    configuration.setProperty("TxNames",txList,"Manager");
  }

  private void DADs() {
    String dadList = properties.getProperty("global.alias");
    StringTokenizer st = new StringTokenizer(dadList, " ");
    while (st.hasMoreElements()) {
        String aliasdef = (String)st.nextElement();
        configuration.setCategory("DAD_"+aliasdef);
        int i;
        String usr = (usr = properties.getProperty(aliasdef + ".dbusername")) != null ? usr : "";
        String pass = (pass = properties.getProperty(aliasdef + ".dbpassword")) != null ? pass : "";
        boolean stateLess = "true".equalsIgnoreCase(properties.getProperty(aliasdef + ".StateLess"));
        String errorPage = (errorPage = properties.getProperty(aliasdef + ".errorPage")) != null ? errorPage : "http://localhost/";
        String dynamicLoginRealm = (dynamicLoginRealm = properties.getProperty(aliasdef + ".dynamicLoginRealm")) != null ?
            dynamicLoginRealm : aliasdef;
        String documentTable = (documentTable = properties.getProperty(aliasdef + ".documentTable")) != null ? documentTable :
            "owa_public.wpg_document";
        String docAccessPath = (docAccessPath = properties.getProperty(aliasdef + ".docAccessPath")) != null ? docAccessPath : "docs";
        String docAccessProcedure = (docAccessProcedure = properties.getProperty(aliasdef + ".docAccessProcedure")) != null ?
            docAccessProcedure : "owa_public.wpg_testdoc.process_download";
        String defaultPage = (defaultPage = properties.getProperty(aliasdef + ".defaultPage")) != null ?
            defaultPage : "wwwIndex.html";
        boolean alwaysCallDefaultPage = "true".equalsIgnoreCase(properties.getProperty(aliasdef + ".alwaysCallDefaultPage"));
        String customAuthentication = (customAuthentication = properties.getProperty(aliasdef + ".customAuthentication")) != null ?
            customAuthentication : "none";
        String compat = (compat = properties.getProperty(aliasdef + ".compat")) != null ? compat : "7x";
        String connectString = (connectString = properties.getProperty(aliasdef + ".connectString")) != null ?
            connectString : "jdbc:oracle:oci8:@";
        try {
            i = (new Integer(properties.getProperty(aliasdef + ".errorLevel"))).intValue();
        } catch (Exception e) { i = 0; };
        String clientCharset = (clientCharset = properties.getProperty(aliasdef + ".clientcharset")) != null ?
            clientCharset : "iso-8859-1";
        String dbCharset = (dbCharset = properties.getProperty(aliasdef + ".dbcharset")) != null ? dbCharset : "iso-8859-1";
        if ("7x".equals(compat)) {
          String type_owner = (type_owner = properties.getProperty(aliasdef + ".type_owner")) != null ? type_owner : "OWA_PUBLIC";
          String type_name = (type_name = properties.getProperty(aliasdef + ".type_name")) != null ? type_name : "OWA_UTIL";
          String type_subname = (type_subname = properties.getProperty(aliasdef + ".type_subname")) != null ?
            type_subname : "IDENT_ARR";
          configuration.setProperty("type_owner",type_owner,"DAD_"+aliasdef);
          configuration.setProperty("type_name",type_name,"DAD_"+aliasdef);
          configuration.setProperty("type_subname",type_subname,"DAD_"+aliasdef);
        }
        configuration.setProperty("dbusername",usr,"DAD_"+aliasdef);
        configuration.setProperty("dbpassword",pass,"DAD_"+aliasdef);
        configuration.setProperty("StateLess",""+stateLess,"DAD_"+aliasdef);
        configuration.setProperty("errorPage",errorPage,"DAD_"+aliasdef);
        configuration.setProperty("dynamicLoginRealm",dynamicLoginRealm,"DAD_"+aliasdef);
        configuration.setProperty("documentTable",documentTable,"DAD_"+aliasdef);
        configuration.setProperty("docAccessPath",docAccessPath,"DAD_"+aliasdef);
        configuration.setProperty("docAccessProcedure",docAccessProcedure,"DAD_"+aliasdef);
        configuration.setProperty("defaultPage",defaultPage,"DAD_"+aliasdef);
        configuration.setProperty("alwaysCallDefaultPage",""+alwaysCallDefaultPage,"DAD_"+aliasdef);
        configuration.setProperty("customAuthentication",customAuthentication,"DAD_"+aliasdef);
        configuration.setProperty("compat",compat,"DAD_"+aliasdef);
        configuration.setProperty("connectString",connectString,"DAD_"+aliasdef);
        configuration.setProperty("errorLevel",""+i,"DAD_"+aliasdef);
        configuration.setProperty("clientcharset",clientCharset,"DAD_"+aliasdef);
        configuration.setProperty("dbcharset",dbCharset,"DAD_"+aliasdef);
        
        // DBConnJava8i specific parameters
        if (compat.startsWith("9i")) {
          String debugHost = properties.getProperty(aliasdef+".debugHost");
          int debugPort = (properties.getProperty(aliasdef+".debugPort")!=null) 
            ? Integer.parseInt(properties.getProperty(aliasdef+".debugPort")) : -1 ;
          if (debugHost!=null) {
            configuration.setProperty("debugHost",debugHost,"DAD_"+aliasdef);
            configuration.setProperty("debugPort",""+debugPort,"DAD_"+aliasdef);    
          }
        } 

        // DBConnJavaLite specific parameters
        if ("lite".equals(compat)) {
          String caseSensity = (caseSensity = properties.getProperty(aliasdef + ".case")) != null ?
                                  caseSensity : "upper";
          configuration.setProperty("case",caseSensity,"DAD_"+aliasdef);
        } 

        // JTA Specific parameters
        String managerClass = properties.getProperty("Manager.class");
        if ("com.prism.oracle.JTADBPrismConnectionCacheImpl".equals(managerClass)) {
          try {
            i = (new Integer(properties.getProperty("Manager." + aliasdef + ".MinLimit"))).intValue();
          } catch (Exception e) { i = 0; };
          configuration.setProperty("MinLimit",""+i,"DAD_"+aliasdef);
          try {
            i = (new Integer(properties.getProperty("Manager." + aliasdef + ".MaxLimit"))).intValue();
          } catch (Exception e) { i = 20; };
          configuration.setProperty("MaxLimit",""+i,"DAD_"+aliasdef);
          try {
            i = (new Integer(properties.getProperty("Manager." + aliasdef + ".LoginTimeout"))).intValue();
          } catch (Exception e) { i = 60; };
          configuration.setProperty("LoginTimeout",""+i,"DAD_"+aliasdef);
          String cacheScheme = ((cacheScheme=properties.getProperty("Manager." + aliasdef + ".CacheScheme"))!=null) ?
                               cacheScheme : "FixedWait" ;
          configuration.setProperty("CacheScheme",cacheScheme,"DAD_"+aliasdef);
        }
    }
  }

  private void Transactions() {
    String txList = properties.getProperty("Manager.TxNames");
    StringTokenizer st = new StringTokenizer(txList, " ");
    while (st.hasMoreElements()) {
        String txdef = (String)st.nextElement();
        configuration.setCategory("TX_"+txdef);
        String BeginURI = properties.getProperty(txdef + ".BeginURI");
        String CommitURI = properties.getProperty(txdef + ".CommitURI");
        String RollBackURI = properties.getProperty(txdef + ".RollBackURI");
        int timeOut = (new Integer(properties.getProperty(txdef + ".TimeOut"))).intValue();
        String BelongTo = properties.getProperty(txdef + ".BelongTo");
        configuration.setProperty("BeginURI",BeginURI,"TX_"+txdef);
        configuration.setProperty("CommitURI",CommitURI,"TX_"+txdef);
        configuration.setProperty("RollBackURI",RollBackURI,"TX_"+txdef);
        configuration.setProperty("TimeOut",""+timeOut,"TX_"+txdef);
        configuration.setProperty("BelongTo",BelongTo,"TX_"+txdef);
    }
  }
  
  public static void main(String[] args) {
    if (args.length!=2) {
      System.err.println("Insufficient arguments in command line");
      System.err.println("Use:");
      System.err.println("    java com.prism.utils.MigrateProperties prism.properties prism.xconf");
      System.exit(0);
    }
    try {
      File propFile = new File(args[0]);
      File confFile = new File(args[1]);
      if (!propFile.canRead()) {
        System.err.println("Can't read '"+args[0]+"'. Exiting...");
        System.exit(0);     
      }
      if (confFile.canWrite()) {
        System.err.println("'"+args[1]+"' exists, I will not override it. Exiting...");
        System.exit(0);     
      }
      if (!confFile.createNewFile()) {
        System.err.println("Can't create '"+args[1]+"'. Exiting...");
        System.exit(0);           
      } else {
        FileOutputStream fop = new FileOutputStream(confFile);
        String initContent = "<?xml version='1.0' encoding='ISO-8859-1'?>\n"+
                             "<!-- Automatically converted from prism.properties format -->\n"+
                             "<properties>\n"+
                             "  <variables>\n"+
                             "    <variable name='demo.path' value='/dpls/sample'/>\n"+
                             "    <variable name='demo.db' value='jdbc:oracle:thin:@localhost:1521:orcl'/>\n"+
                             "  </variables>\n"+
                             "  <category name='general'>\n"+
                             "  </category>\n"+
                             "</properties>\n";
        fop.write(initContent.getBytes());
        fop.close();
      }
      MigrateProperties migrateProperties = new MigrateProperties(propFile,confFile);
      migrateProperties.global();
      migrateProperties.Factories();
      migrateProperties.Drivers();
      migrateProperties.DADs();
      migrateProperties.Manager();
      migrateProperties.Transactions();
      migrateProperties.save();
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(0);
    }
  }
}